# src/visualization.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import gridspec
import os

# 设置中文字体和图表样式
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.figsize'] = (10, 6)

class DataVisualizer:
    def __init__(self):
        """初始化可视化器，加载数据"""
        print("正在加载数据...")
        
        # 加载销售数据
        self.sales_data = pd.read_csv('data/raw/sales_data.csv')
        self.sales_data['order_date'] = pd.to_datetime(self.sales_data['order_date'])
        
        # 加载员工数据  
        self.employee_data = pd.read_csv('data/raw/user_behavior.csv')
        self.employee_data['hire_date'] = pd.to_datetime(self.employee_data['hire_date'])
        
        print("数据加载完成！")
    
    def create_region_sales_chart(self):
        """创建区域销量分布图表"""
        print("生成区域销量分布图表...")
        
        plt.figure(figsize=(14, 10))
        
        # 计算各区域销量
        region_sales = self.sales_data.groupby('region')['total_amount'].sum().sort_values(ascending=False)
        
        # 设置颜色
        colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD']
        
        # 创建柱状图
        bars = plt.bar(region_sales.index, region_sales.values, color=colors, alpha=0.8, edgecolor='black')
        
        # 添加数据标签
        for i, (region, value) in enumerate(region_sales.items()):
            plt.text(i, value + 100, f'{value:,.0f}', 
                    ha='center', va='bottom', fontsize=12, fontweight='bold')
        
        # 设置图表样式
        plt.title('月各区域销量分布', fontsize=18, fontweight='bold', pad=20)
        plt.xlabel('区域', fontsize=14)
        plt.ylabel('销量金额 (元)', fontsize=14)
        plt.grid(axis='y', alpha=0.3)
        
        # 添加注释
        max_region = region_sales.index[0]
        min_region = region_sales.index[-1]
        max_percent = (region_sales[max_region] / region_sales.sum()) * 100
        min_percent = (region_sales[min_region] / region_sales.sum()) * 100
        
        annotation_text = f'{max_region}销量最多占比总销量的{max_percent:.1f}%，{min_region}销量最低'
        plt.figtext(0.5, 0.01, annotation_text, ha='center', fontsize=12, 
                    style='italic', bbox={'facecolor': 'lightgray', 'alpha': 0.3, 'pad': 5})
        
        # 添加底部注记
        plt.figtext(0.5, -0.05, '*注：数据来源于公司销售系统，统计日期截至2022.03.31', 
                    ha='center', fontsize=10, style='italic')
        
        plt.tight_layout()
        plt.savefig('outputs/charts/region_sales_distribution.png', dpi=300, bbox_inches='tight')
        plt.show()
        
        print("区域销量分布图表已保存: outputs/charts/region_sales_distribution.png")
    
    def create_age_distribution_chart(self):
        """创建年龄段分布图表"""
        print("生成年龄段分布图表...")
        
        plt.figure(figsize=(12, 10))
        
        # 计算年龄段分布
        bins = [20, 30, 40, 50, 65]
        labels = ['[20,30]', '[30,40]', '[40,50]', '>=50']
        self.employee_data['age_group'] = pd.cut(self.employee_data['age'], bins=bins, labels=labels, right=False)
        age_dist = self.employee_data['age_group'].value_counts().reindex(labels)
        
        # 计算百分比
        percentages = (age_dist / age_dist.sum() * 100).round(1)
        
        # 设置颜色
        colors = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99']
        
        # 创建饼图
        wedges, texts, autotexts = plt.pie(age_dist.values, labels=age_dist.index, 
                                          colors=colors, autopct='%1.1f%%', 
                                          startangle=90, textprops={'fontsize': 12})
        
        # 美化百分比文本
        for autotext in autotexts:
            autotext.set_color('white')
            autotext.set_fontweight('bold')
            autotext.set_fontsize(11)
        
        # 设置标题
        avg_age = self.employee_data['age'].mean()
        plt.title(f'2022年上半年年龄段人数分布\n公司平均年龄{avg_age:.1f}，{age_dist.index[0]}员工比例最高占比{percentages.iloc[0]}%', 
                  fontsize=16, fontweight='bold', pad=20)
        
        # 添加底部注记
        plt.figtext(0.5, 0.02, '*注：数据来源于公司人力资源系统，统计日期截至2022.06.30', 
                    ha='center', fontsize=10, style='italic')
        
        plt.tight_layout()
        plt.savefig('outputs/charts/age_distribution.png', dpi=300, bbox_inches='tight')
        plt.show()
        
        print("年龄段分布图表已保存: outputs/charts/age_distribution.png")
    
    def create_employee_dashboard(self):
        """创建员工结构仪表板"""
        print("生成员工结构仪表板...")
        
        fig = plt.figure(figsize=(20, 12))
        
        # 定义网格布局
        gs = gridspec.GridSpec(3, 4, figure=fig)
        
        # 1. 年龄分布饼图
        ax1 = fig.add_subplot(gs[0, 0])
        age_bins = [25, 30, 35, 40, 65]
        age_labels = ['25-29', '30-34', '35-39', '40>=']
        self.employee_data['age_detail'] = pd.cut(self.employee_data['age'], bins=age_bins, labels=age_labels, right=False)
        age_detail_dist = self.employee_data['age_detail'].value_counts().reindex(age_labels)
        
        colors_age = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFEAA7']
        wedges1, texts1, autotexts1 = ax1.pie(age_detail_dist.values, labels=age_detail_dist.index, 
                                             colors=colors_age, autopct='%1.0f%%', startangle=90)
        ax1.set_title('年龄', fontsize=14, fontweight='bold')
        
        # 2. 性别分布饼图
        ax2 = fig.add_subplot(gs[0, 1])
        gender_dist = self.employee_data['gender'].value_counts()
        colors_gender = ['#66B2FF', '#FF9999']
        wedges2, texts2, autotexts2 = ax2.pie(gender_dist.values, labels=gender_dist.index, 
                                             colors=colors_gender, autopct='%1.0f%%', startangle=90)
        ax2.set_title('性别', fontsize=14, fontweight='bold')
        
        # 3. 婚姻状况饼图
        ax3 = fig.add_subplot(gs[0, 2])
        marital_dist = self.employee_data['marital_status'].value_counts()
        colors_marital = ['#99FF99', '#FFCC99', '#DDA0DD']
        wedges3, texts3, autotexts3 = ax3.pie(marital_dist.values, labels=marital_dist.index, 
                                             colors=colors_marital, autopct='%1.0f%%', startangle=90)
        ax3.set_title('婚姻状况', fontsize=14, fontweight='bold')
        
        # 4. 学历分布饼图
        ax4 = fig.add_subplot(gs[0, 3])
        education_dist = self.employee_data['education'].value_counts()
        colors_edu = ['#FFB6C1', '#98FB98', '#87CEEB', '#DDA0DD']
        wedges4, texts4, autotexts4 = ax4.pie(education_dist.values, labels=education_dist.index, 
                                             colors=colors_edu, autopct='%1.0f%%', startangle=90)
        ax4.set_title('学历', fontsize=14, fontweight='bold')
        
        # 5. 部门分布条形图
        ax5 = fig.add_subplot(gs[1:, :2])
        dept_dist = self.employee_data['department'].value_counts().sort_values(ascending=True)
        bars = ax5.barh(dept_dist.index, dept_dist.values, color=plt.cm.Set3(np.arange(len(dept_dist))))
        
        # 添加数据标签
        for i, (dept, count) in enumerate(dept_dist.items()):
            ax5.text(count + 5, i, str(count), va='center', fontsize=11, fontweight='bold')
        
        ax5.set_title('部门分布', fontsize=14, fontweight='bold')
        ax5.set_xlabel('员工数量')
        
        # 6. 总人数和流动情况
        ax6 = fig.add_subplot(gs[1, 2:])
        ax6.axis('off')
        
        total_employees = len(self.employee_data)
        hire_data = [40, 5, 5]
        hire_labels = ['入职', '转入', '转出']
        
        # 显示总人数
        ax6.text(0.1, 0.8, f'总人数: {total_employees}', fontsize=16, fontweight='bold', 
                 transform=ax6.transAxes)
        
        # 显示流动情况
        ax6.text(0.1, 0.6, '入转调', fontsize=12, fontweight='bold', transform=ax6.transAxes)
        for i, (label, value) in enumerate(zip(hire_labels, hire_data)):
            ax6.text(0.1 + i * 0.2, 0.5, f'{value}', fontsize=14, fontweight='bold', 
                    ha='center', transform=ax6.transAxes)
            ax6.text(0.1 + i * 0.2, 0.4, label, fontsize=10, ha='center', transform=ax6.transAxes)
        
        # 设置主标题
        fig.suptitle('公司人员结构看板', fontsize=20, fontweight='bold', y=0.95)
        
        plt.tight_layout()
        plt.savefig('outputs/charts/employee_dashboard.png', dpi=300, bbox_inches='tight')
        plt.show()
        
        print("员工结构仪表板已保存: outputs/charts/employee_dashboard.png")
    
    def create_all_charts(self):
        """生成所有图表"""
        print("开始生成所有可视化图表...")
        
        self.create_region_sales_chart()
        self.create_age_distribution_chart() 
        self.create_employee_dashboard()
        
        print("\n所有图表生成完成！")
        print("图表文件保存在 outputs/charts/ 目录下")

# 添加以下main函数
def main():
    """可视化主函数 - 供main.py调用"""
    visualizer = DataVisualizer()
    visualizer.create_all_charts()

if __name__ == "__main__":
    # 当直接运行此脚本时
    main()